package zunge.lbe.analysis;

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.Arrays;

import zunge.tools.Tools;
import blog.common.BipartiteMatcher;

public class M_ClusterStability {
	static int FOLD = 10;//5;//10;
	static int UCOUNT = 239403;
	
	public static void main(String args[]){
		try{
			for(int k = 2;k <= 20;++k){
				int[][] labels = new int[FOLD+1][UCOUNT]; for(int i = 0;i < FOLD+1;++i){Arrays.fill(labels[i], 0);}
				BufferedReader br = new BufferedReader(new FileReader(
						//"/usr0/home/bliu1/BinWork/Workspace/LBE_ANALYSIS_3/data/clustering/stability_k"+k+".txt"));
						"/usr0/home/bliu1/BinWork/Workspace/LBE_ANALYSIS_3/data/clustering/stability_f10_k"+k+".txt"));
				br.readLine(); //Skip title
				for(int u = 0;u < UCOUNT;++u){
					String[] frags = br.readLine().split(" ");
					for(int f = 0;f < FOLD+1;++f){
						labels[f][u] = Integer.parseInt(frags[f+1]);
					}
				}
				br.close();
				
				double[] sims = new double[FOLD];
				//System.out.print("k="+k);
				for(int f = 0;f < FOLD;++f){
					sims[f] = getSim(labels[0], labels[f+1], k);
					//System.out.printf(" %1$.2f",sims[f]);
				}
				//System.out.print("===");
				
				System.out.println(k+" "+Tools.getAverage(sims)+" "+Tools.getVariance(sims));
			}
			
		}catch(Exception e){e.printStackTrace();}
	}
	static double getSim(int[] label1, int[] label2, int K){
		int[][] links = new int[K][K]; for(int i = 0;i < K;++i){Arrays.fill(links[i], 0);}
		for(int i1 = 0;i1 < K;++i1){
			for(int i2 = 0;i2 < K;++i2){
				for(int i = 0;i < label1.length;++i){
					if(label1[i]==i1+1 && label2[i]==i2+1){links[i1][i2]++;}
				}
			}
		}
		BipartiteMatcher bm = new BipartiteMatcher(K);
		for(int i1 = 0;i1 < K;++i1){
			for(int i2 = 0;i2 < K;++i2){
				//System.out.println("link["+i1+"]["+i2+"]="+links[i1][i2]);
				bm.setWeight(i1, i2, links[i1][i2]);
			}
		}
		int[] matching = bm.getMatching();
		double totalMatches = 0;
		for(int i = 0;i < K;++i){
			//System.out.println(i+"="+matching[i]);
			totalMatches += links[i][matching[i]];
		}
		return totalMatches / UCOUNT;
	}
	
}
